package com.emagic.manage.common.ui.base;


import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.IdRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import com.bumptech.glide.Glide;
import com.emagic.manage.R;
import com.emagic.manage.common.consts.SysParams;
import com.emagic.manage.data.exception.BizException;
import com.emagic.manage.data.exception.ServerError;
import com.emagic.manage.mvp.views.LoadDataView;
import com.emagic.manage.navigation.Navigator;
import com.emagic.manage.utils.ToastUtil;
import com.xitaiinfo.library.compat.errorview.ErrorView;
import com.xitaiinfo.library.compat.widget.BetterViewAnimator;
import com.xitaiinfo.library.injections.HasComponent;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.List;

import butterknife.ButterKnife;
import butterknife.Unbinder;
import dagger.android.support.AndroidSupportInjection;
import dagger.android.support.DaggerFragment;
import retrofit2.adapter.rxjava.HttpException;


/**
 * Base {@link Fragment} class for every fragment in this application.
 *
 * @author baoy
 * @version 1.0
 *          Create by 15/12/30 下午4:26
 */
public abstract class BaseFragment extends DaggerFragment implements LoadDataView {

    FrameLayout mContentView;
    ErrorView mErrorView;
    BetterViewAnimator mViewAnimator;

    private Handler mHandler = new Handler(Looper.getMainLooper());

    private Unbinder unbinder;

    /**
     * 根据入参componentType获取一个依赖注入的component
     */
    @SuppressWarnings("unchecked")
    @Deprecated
    protected <C> C getComponent(Class<C> componentType) {
        return componentType.cast(((HasComponent<C>) getActivity()).getComponent());
    }

    protected Navigator getNavigator() {

        if (getActivity() instanceof BaseActivity) {
            return ((BaseActivity) getActivity()).getNavigator();
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Nullable
    protected final <V extends View> V $(@NonNull View view, @IdRes int id) {
        return (V) view.findViewById(id);
    }

    public boolean isEmpty(List<?> list) {
        return list == null || list.isEmpty();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        AndroidSupportInjection.inject(this);
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onStop() {
        super.onStop();
        mHandler.post(() -> Glide.get(getContext()).clearMemory());
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_base_layout, container, false);
        View childView = inflater.inflate(setupContentView(), null);

        this.mContentView = $(view, R.id.content_view);
        this.mErrorView = $(view, R.id.error_view);
        this.mViewAnimator = $(view, R.id.view_animator);

        mContentView.addView(childView);

        unbinder = ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (unbinder != null)
            unbinder.unbind();
    }

    protected void addView(View v) {
        addView(v, mContentView.getChildCount());
    }

    protected void addView(View v, int index) {
        mContentView.addView(v, index);
    }

    protected void removeView(View v) {
        mContentView.removeView(v);
    }

    protected void setFitsSystemWindows(boolean fitSystemWindows) {
        mViewAnimator.setFitsSystemWindows(fitSystemWindows);
    }

    protected abstract
    @LayoutRes
    int setupContentView();

    @Override
    public void showLoadingView() {
        mViewAnimator.setDisplayedChildId(R.id.loading_view);
    }

    @Override
    public void showEmptyView(ErrorView.Config errorConfig, ErrorView.OnRetryListener onRetryListener) {
        ErrorViewFactory.buildEmptyErrorView(mErrorView, errorConfig, onRetryListener);
        mViewAnimator.setDisplayedChildId(R.id.error_view);
    }

    @Override
    public void showErrorView(Throwable throwable, ErrorView.Config errorConfig, ErrorView.OnRetryListener onRetryListener) {
        if (throwable != null) {
            //log错误文本
            Log.e(SysParams.ERROR_TAG, "showErrorView: " + throwable.getMessage(), throwable);
        }
        if (throwable != null && throwable instanceof BizException) {
            ErrorViewFactory.buildLoadFailErrorView(mErrorView, errorConfig, onRetryListener);
        } else if (throwable != null && throwable instanceof UnknownHostException) {
            ErrorViewFactory.buildNoNetworkErrorView(mErrorView, errorConfig, onRetryListener);
        } else if (throwable != null && throwable instanceof HttpException) {
            ErrorViewFactory.buildLoadFailErrorView(mErrorView, errorConfig, onRetryListener);
        } else if (throwable != null && throwable instanceof ConnectException) {
            ErrorViewFactory.buildLoadFailErrorView(mErrorView, errorConfig, onRetryListener);
        } else if (throwable != null && throwable instanceof SocketTimeoutException) {
            ErrorViewFactory.buildLoadFailErrorView(mErrorView, errorConfig, onRetryListener);
        } else if (throwable != null && throwable instanceof ServerError) {
            ErrorViewFactory.buildServerErrorView(mErrorView, errorConfig, onRetryListener);
        } else {
            ErrorViewFactory.buildLoadFailErrorView(mErrorView, errorConfig, onRetryListener);
        }
        //show error view
        mViewAnimator.setDisplayedChildId(R.id.error_view);
    }

    @Override
    public void onLoadingComplete() {
        mViewAnimator.setDisplayedChildId(R.id.content_view);
    }

    @Override
    public void showError(String message) {
//        Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
        ToastUtil.showMiddleScreenToast(getContext(), message);
    }
}
